<?php
class Mozg_Module
{
	/**
	 * объекты модулей
	 */
	static private $_modules = array();
	
    /**
		список доступных модулей
     */
    static private $_moduleList;
    static private $_modulesById;
    
    /**
		список контроллеров для модулей
     */
    static private $_ctrlList = array();
    static private $_ctrlsById = array();
    
    /**
		список экшенов для контроллеров
     */
    static private $_ctrlActionList = array();
    static private $_ctrlActionsById = array();

	private function __construct (){}
    
    /**
		возвращает объект модуля
     */
    static public function Get($moduleName, $protName = false, $envName = false)
    {
		if (!isset(self::$_modules[$moduleName][$protName][$envName]))
		{
			self::$_modules[$moduleName][$protName][$envName] = self::CreateModule($moduleName, $protName, $envName);
		}
		
		return self::$_modules[$moduleName][$protName][$envName];
    }

    static protected function CreateModule($moduleName, $protName, $envName)
    {
		$moduleClassName = 'App_Module_' .$moduleName. '_Module_' .$protName. '_' .$envName;
        if (!class_exists($moduleClassName))
        {
        	$moduleClassName = 'App_Module_' .$moduleName. '_Module_' .$protName;
        	if (!class_exists($moduleClassName))
        	{
        		$moduleClassName = 'App_Module_' .$moduleName. '_Module_Base';
        		if (!class_exists($moduleClassName))
        		{
        			throw new Mozg_Exception_NotFound('Модуль ' . $moduleName . ' не найден');
        		}
        	}
        }
		
        return new $moduleClassName($protName, $envName);
    }

    /**
		возвращает список модулей
     */
    static public function GetList()
    {
        if (is_array(self::$_moduleList)) return self::$_moduleList;
        
        self::$_moduleList = self::$_modulesById = array();
        
        //загружаем список модулей
        if (Mozg_Storage::Exists(_APP_PATH . 'Module/modules'))
        {
            self::$_moduleList = (array)Mozg_Storage::Read(_APP_PATH . 'Module/modules');
            foreach (self::$_moduleList as $name => $data)
            {
            	self::$_modulesById[$data['id']] = $name;
            }
        }
        
        return self::$_moduleList;
    }
    
    static public function GetNameById($id)
    {
        self::GetList();
        return (isset(self::$_modulesById[$id]) ? self::$_modulesById[$id] : false);
    }
    
    /**
		загружаем список контроллеров для модуля
     */
    static public function GetCtrlList($moduleName)
    {
    	$moduleName = strtolower($moduleName);
    	
        if (!self::IsInList($moduleName)) return array();
        if (is_array(self::$_ctrlList[$moduleName])) return self::$_ctrlList[$moduleName];

        self::$_ctrlList[$moduleName] = self::$_ctrlsById[$moduleName] = array();
        
        //загружаем список контроллеров
        if (Mozg_Storage::Exists(self::GetPath($moduleName). 'Component/components'))
        {
        	self::$_ctrlList[$moduleName] = (array)Mozg_Storage::Read(self::GetPath($moduleName). 'Component/components');
        	foreach (self::$_ctrlList[$moduleName] as $name => $data)
        	{
        		self::$_ctrlsById[$moduleName][$data['id']] = $name;
        	}
        }
        
        return self::$_ctrlList[$moduleName];
    }
    
    static public function GetCtrlNameById($moduleId, $ctrlId)
    {
    	$moduleName = self::GetNameById($moduleId);
    	if ($moduleName === false) throw new Mozg_Exception_System(Mozg_Lang::_('MODULE_NOT_FOUND'));
        self::GetCtrlList($moduleName);

        return (isset(self::$_ctrlsById[$moduleName][$ctrlId]) ? self::$_ctrlsById[$moduleName][$ctrlId] : false);
    }
    
    static public function IsCtrlInList($moduleName, $ctrlName)
    {
    	$moduleName = strtolower($moduleName);
    	$ctrlName = strtolower($ctrlName);
    	
        self::GetCtrlList($moduleName);
        return isset(self::$_ctrlList[$moduleName][$ctrlName]);
    }
    
    /**
		возвращает данные контроллера по его имени
     */
    static public function GetCtrlDetails($moduleName, $ctrlName)
    {
    	$moduleName = strtolower($moduleName);
    	$ctrlName = strtolower($ctrlName);
    	
        if (! self::IsCtrlInList($moduleName, $ctrlName)) return array(
		                                                                'id' => 0,
		                                                                'title' => '',
		                                                        );
        return self::$_ctrlList[$moduleName][$ctrlName];
    }
    
    /**
		список экшенов для контроллера
     */
    static public function GetCtrlActionList($moduleName, $ctrlName)
    {
    	$moduleName = strtolower($moduleName);
    	$ctrlName = strtolower($ctrlName);
    	
        if (!self::IsCtrlInList($moduleName, $ctrlName)) return array();
        if (isset(self::$_ctrlActionList[$moduleName][$ctrlName])) return self::$_ctrlActionList[$moduleName][$ctrlName];
        
        self::$_ctrlActionList[$moduleName][$ctrlName] = self::$_ctrlActionsById[$moduleName][$ctrlName] = array();
        
        $ctrlPath = Mozg_Controller::GetCtrlPath($moduleName, $ctrlName);

        if (Mozg_Storage::Exists($ctrlPath . 'actions'))
        {
        	self::$_ctrlActionList[$moduleName][$ctrlName] = (array)Mozg_Storage::Read($ctrlPath . 'actions');
			foreach (self::$_ctrlActionList[$moduleName][$ctrlName] as $name => $data)
        	{
        		self::$_ctrlActionsById[$moduleName][$ctrlName][$data['id']] = $name;
        	}
        }

		return self::$_ctrlActionList[$moduleName][$ctrlName];
    }
    
    static function GetCtrlActionIds($moduleId, $ctrlId)
    {
    	$moduleName = self::GetNameById($moduleId);
    	if ($moduleName === false) throw new Mozg_Exception_System(Mozg_Lang::_('MODULE_NOT_FOUND'));
    	
    	$ctrlName = self::GetCtrlNameById($moduleId, $ctrlId);
        if ($ctrlName === false) throw new Mozg_Exception_System(Mozg_Lang::_('CONTROLLER_NOT_FOUND'));

        self::GetCtrlActionList($moduleName, $ctrlName);
        
        return (isset(self::$_ctrlActionsById[$moduleName][$ctrlName]) ? array_keys(self::$_ctrlActionsById[$moduleName][$ctrlName]) : array());
    }
    
    static public function GetCtrlActionNameById($moduleId, $ctrlId, $actionId)
    {
    	$moduleName = self::GetNameById($moduleId);
    	if ($moduleName === false) throw new Mozg_Exception_System(Mozg_Lang::_('MODULE_NOT_FOUND'));
    	
    	$ctrlName = self::GetCtrlNameById($moduleId, $ctrlId);
        if ($ctrlName === false) throw new Mozg_Exception_System(Mozg_Lang::_('CONTROLLER_NOT_FOUND'));

        self::GetCtrlActionList($moduleName, $ctrlName);
        
        return (isset(self::$_ctrlActionsById[$moduleName][$ctrlName][$actionId]) ? self::$_ctrlActionsById[$moduleName][$ctrlName][$actionId] : false);
    }
    
    static public function IsActionInList($moduleName, $ctrlName, $actionName)
    {
    	$moduleName = strtolower($moduleName);
    	$ctrlName = strtolower($ctrlName);
    	$actionName = strtolower($actionName);
    	
        self::GetCtrlActionList($moduleName, $ctrlName);
        return isset(self::$_ctrlActionList[$moduleName][$ctrlName][$actionName]);
    }
    
    static public function GetActionDetails($moduleName, $ctrlName, $actionName)
    {
    	$moduleName = strtolower($moduleName);
    	$ctrlName = strtolower($ctrlName);
    	$actionName = strtolower($actionName);
    	
        if (! self::IsActionInList($moduleName, $ctrlName, $actionName)) return array(
		                                                                'id' => 0,
		                                                                'title' => '',
		                                                        );
        return self::$_ctrlActionList[$moduleName][$ctrlName][$actionName];
    }
    
    /**
		проверяем есть ли модуль в списке модулей
     */
    static public function IsInList($moduleName)
    {
    	$moduleName = strtolower($moduleName);
    	
        self::GetList();
        return isset(self::$_moduleList[$moduleName]);
    }
    
    /**
		возвращает данные модуля из спика модулей
     */
    static public function GetDetails($moduleName)
    {
    	$moduleName = strtolower($moduleName);
    	
        if (! self::IsInList($moduleName)) return array(
                                                                'id' => 0,
                                                                'title' => '',
                                                        );
        return self::$_moduleList[$moduleName];
    }
    
    static public function GetId($moduleName)
    {
    	$moduleName = strtolower($moduleName);
    	
        if (!self::IsInList($moduleName)) return 0;
        return self::$_moduleList[$moduleName]['id'];
    }
    
    static public function GetTitle($moduleName)
    {
    	$moduleName = strtolower($moduleName);
    	
        if (!self::IsInList($moduleName)) return '';
        return self::$_moduleList[$moduleName]['title'];
    }
    
    static public function GetPath($moduleName)
    {
    	$moduleName = strtolower($moduleName);
        return _APP_PATH.self::GetFolder($moduleName);
    }
    
    static public function GetFolder($moduleName)
    {
    	$moduleName = strtolower($moduleName);
        return 'Module/' .ucwords($moduleName). '/';
    }
}